package disk;

import java.util.ArrayList;

import util.ByteUtil;

/**
 * 目录类
 * 
 * @author vincent
 * 
 */
public class Directory {
	/**
	 * 每个目录占用1个盘块
	 */
	private Block block = null;
	/**
	 * 目录名
	 */
	private String dirName = null;

	/**
	 * 构造函数
	 * 
	 * @param block
	 */
	public Directory(Block block, String dirName) {
		// TODO 自动生成的构造函数存根
		this.block = block;
		this.dirName = dirName;
	}

	/**
	 * 获取目录所占用的盘块
	 * 
	 * @return
	 */
	public Block getBlock() {
		return block;
	}

	/**
	 * 获取路径名
	 * 
	 * @return
	 */
	public String getDirName() {
		return dirName;
	}

	/**
	 * 获取能使用的目录项位置(0~7)
	 * 
	 * @return
	 */
	private int getFreeDirectoryEntryIndex() {
		// 最多8个文件 每项占8字节
		for (int index = 0; index < 8; index++) {
			// 已经使用的目录项第一个字节不能为0
			if (block.getByte(8 * index) == 0) {
				return index;
			}
		}
		return -1;
	}

	/**
	 * 判断当前目录下是否能够继续添加目录项
	 * 
	 * @return
	 */
	private boolean canAddDirectoryEntry() {
		// 判断是否能够获取能使用的目录项位置
		if (getFreeDirectoryEntryIndex() != -1) {
			return true;
		}
		return false;
	}

	/**
	 * 判断目录项是否存在
	 * 
	 * @param dirEntryName
	 * @return
	 */
	public boolean exist(String dirEntryName) {
		if (getDirectoryEntryIndex(dirEntryName) != -1) {
			return true;
		}
		return false;
	}

	/**
	 * 添加文件
	 * 
	 * @param file
	 */
	public boolean addFile(File file) {
		// 判断文件名是否合理
		if (file.getName().length > 3) {
			System.out.println("文件名过长");
			return false;
		}
		if (file.getTypeName().length > 2) {
			System.out.println("文件后缀名过长");
			return false;
		}
		// 判断是否能再创建文件
		if (!canAddDirectoryEntry()) {
			System.out.println(dirName + "目录下的文件数量已达8个");
			return false;
		}
		// 判断文件是否存在
		if (exist(file.getCompleteName())) {
			System.out.println("文件:" + getAbsolutePath(file.getCompleteName())
					+ "已存在");
			return false;
		}

		// 获取磁盘引用
		Disk disk = Disk.getInstance();
		FAT fat = disk.getFat();

		// 设置文件的各种属性
		int contentBytes = file.getContent().length; // 获取文件内容的长度
		int allocateBytes = contentBytes + 4; // 分配给文件的字节数(4个字节用于记录文件的实际长度)
		// 判断文件需要占用多少个盘块
		int blockLength = Block.getBlockLength(allocateBytes);

		file.setLength((byte) blockLength); // 文件占用的盘块数
		file.addAttribute(FileAttribute.ISCOMMONFILE); // 添加普通文件属性

		// 为文件分配盘块
		byte[] blockIndexes = fat.allocateBlock((byte) blockLength);
		// 判断是否有足够的空间
		if (blockIndexes == null) {
			System.out.println("磁盘空间不足");
			return false;
		}
		file.setBlockIndex(blockIndexes[0]); // 记录起始盘块号

		// 添加目录项
		addDirectoryEntry(file);
		// 保存文件内容到分配的盘块
		saveFileContent(file.getContent(), blockIndexes);

		// ---------------------
		System.out.println("创建文件:" + getAbsolutePath(file.getCompleteName())
				+ " 文件实际长度:" + blockLength + " 字节数:" + contentBytes);
		System.out.print("占用的盘块:[ ");
		for (int i = 0; i < blockIndexes.length; i++) {
			byte b = blockIndexes[i];
			System.out.print(b);
			System.out.print(" ");
		}
		System.out.println("]\n----------------");
		// ---------------------
		return true;
	}

	/**
	 * 添加目录
	 * 
	 * @param floder
	 */
	public boolean addFolder(Folder folder) {
		// 判断目录名是否合理
		if (folder.getCompleteName().length() > 3) {
			System.out.println("目录名过长");
			return false;
		}
		// 判断是否能再创建文件
		if (!canAddDirectoryEntry()) {
			System.out.println(dirName + "目录下的文件数量已达8个");
			return false;
		}
		// 判断文件是否存在
		if (exist(folder.getCompleteName())) {
			System.out.println("目录:"
					+ getAbsolutePath(folder.getCompleteName()) + "已存在");
			return false;
		}

		// 获取磁盘引用
		Disk disk = Disk.getInstance();
		FAT fat = disk.getFat();

		// 设置文件夹的各种属性(文件夹只有名字)
		folder.setTypeName(new byte[] { 0, 0 });
		folder.setLength((byte) 0);
		folder.addAttribute(FileAttribute.ISFOLDER);// 添加目录属性

		// 为目录分配盘块
		byte[] blockIndexes = fat.allocateBlock((byte) 1); // 目录占用一个盘块
		// 判断是否有足够的空间
		if (blockIndexes == null) {
			System.out.println("磁盘空间不足");
			return false;
		}
		folder.setBlockIndex(blockIndexes[0]); // 记录起始盘块号

		// 添加目录项
		addDirectoryEntry(folder);

		// ---------------------
		System.out.println("创建目录:" + getAbsolutePath(folder.getCompleteName()));
		System.out.print("占用的盘块:[ ");
		for (int i = 0; i < blockIndexes.length; i++) {
			byte b = blockIndexes[i];
			System.out.print(b);
			System.out.print(" ");
		}
		System.out.println("]\n----------------");
		// ---------------------
		return true;
	}

	/**
	 * 写入文件内容到已分配到的盘块
	 * 
	 * @param content
	 * @param blockIndexes
	 */
	private boolean saveFileContent(byte[] content, byte[] blockIndexes) {
		// 获取磁盘引用
		Disk disk = Disk.getInstance();
		int contentBytes = content.length; // 文件内容长度
		byte[] bytes = ByteUtil.intToByteArray(contentBytes);
		Block firstBlock = disk.getBlock(blockIndexes[0]); // 文件占用的首个盘块
		for (int i = 0; i < 4; i++) { // 首个盘块前四个字节用于保存文件内容实际长度
			firstBlock.setByte(i, bytes[i]);
		}

		int hasWrite = 0; // 已经保存的字节数
		for (int i = 4; i < 64; i++) {
			if (hasWrite == contentBytes) {
				return true;
			}
			firstBlock.setByte(i, content[hasWrite++]);
		}

		for (int i = 1; i < blockIndexes.length; i++) {
			Block block = disk.getBlock(blockIndexes[i]);
			for (int j = 0; j < 64; j++) {
				if (hasWrite == contentBytes) {
					return true;
				}
				block.setByte(j, content[hasWrite++]);
			}
		}
		return false;
	}

	/**
	 * 读取文件内容
	 * 
	 * @param blockIndex
	 * @return
	 */
	private byte[] getFileContent(int blockIndex) {
		// 获取磁盘引用
		Disk disk = Disk.getInstance();
		ArrayList<Byte> blockIndexes = disk.getFat().getFileAllocateList(blockIndex);// 获取文件占用的盘块索引值
		Block firstBlock = disk.getBlock(blockIndexes.get(0)); // 文件占用的首个盘块
		// 起始盘块前4字节表示文件实际内容长度
		int contentBytes = ByteUtil.byteArrayToInt(firstBlock.getBytes(0, 3));
		// 文件实际内容
		byte[] content = new byte[contentBytes];

		int hasRead = 0; // 已经保存的字节数
		for (int i = 4; i < 64; i++) {
			if (hasRead == contentBytes) {
				return content;
			}
			content[hasRead++] = firstBlock.getByte(i);
		}

		for (int i = 1; i < blockIndexes.size(); i++) {
			Block block = disk.getBlock(blockIndexes.get(i));
			for (int j = 0; j < 64; j++) {
				if (hasRead == contentBytes) {
					return content;
				}
				content[hasRead++] = block.getByte(j);
			}
		}
		return content;
	}

	/**
	 * 往目录下添加目录项
	 * 
	 * @param entry
	 */
	private boolean addDirectoryEntry(DirectoryEntry entry) {
		int index = getFreeDirectoryEntryIndex();// 从前往后搜索一个能存放目录项的空闲位置
		if (index != -1) {
			// 设置该空闲位置的目录项的值
			setDirectoryEntryValue(index, entry.getName(), entry.getTypeName(), entry.getAttribute(), entry.getBlockIndex(), entry.getLength());
		}
		return false;
	}

	/**
	 * 删除目录下的目录项(包括普通文件和目录)
	 * 
	 * @param entry
	 */
	private boolean removeDirectoryEntry(String dirEntryName) {
		int index = getDirectoryEntryIndex(dirEntryName);
		if (index != -1) {
			// 把该目录项的8个字节全部清零
			setDirectoryEntryValue(index, new byte[] { 0, 0, 0 }, new byte[] {
					0, 0 }, (byte) 0, (byte) 0, (byte) 0);
		}
		return false;
	}

	/**
	 * 设定指定位置的目录项(0~7)的各属性的值
	 * 
	 * @param entry
	 */
	private void setDirectoryEntryValue(int index, byte[] name,
			byte[] typeName, byte attribute, byte blockIndex, byte length) {
		int startIndex = index * 8; // 获取该目录项在盘块中的真实位置
		// 设置目录项的名字(第0～2字节)
		for (int i = 0; i < name.length; i++) {
			this.block.setByte(startIndex++, name[i]);
		}
		startIndex = index * 8 + 3;
		// 设置目录项的类型名(第3～4字节)
		for (int i = 0; i < typeName.length; i++) {
			this.block.setByte(startIndex++, typeName[i]);
		}
		startIndex = index * 8 + 5;
		// 设置目录项属性、起始盘块号、占用的盘块数
		this.block.setByte(startIndex++, attribute);
		this.block.setByte(startIndex++, blockIndex);
		this.block.setByte(startIndex, length);
	}

	/**
	 * 根据目录项名字获取指定目录项存放的位置(0~7)
	 * 
	 * @param dirEntryName
	 * @param fileAttribute
	 * @return
	 */
	private int getDirectoryEntryIndex(String dirEntryName) {
		for (int index = 0; index < 8; index++) {
			// 获取第index个目录项
			DirectoryEntry entry = getDirectoryEntry(index);
			// 判断是否存在目录项
			if (entry == null) {
				continue;
			}
			// 获取目录项的完整名字
			String completeName = entry.getCompleteName();
			if (dirEntryName.equals(completeName)) {
				return index;
			}

		}
		return -1;
	}

	/**
	 * 获取目录下的第index(0~7)个目录项
	 * 
	 * @param index
	 * @return
	 */
	public DirectoryEntry getDirectoryEntry(int index) {
		DirectoryEntry directoryEntry = null;
		int startIndex = index * 8; // 每个目录项占用8个字节
		// 目录项第一个字节不能为0
		if (block.getByte(startIndex) == 0) {
			return null;
		}
		// 名字(第0、1、2字节为名字)
		byte[] name = block.getBytes(startIndex + 0, startIndex + 2);
		// 类型名(第3、4字节为类型)
		byte[] typeName = block.getBytes(startIndex + 3, startIndex + 4);
		// 文件属性(第5字节为属性)
		byte attribute = block.getByte(startIndex + 5);
		// 文件所占用的起始盘块号(第6字节为起始盘块号)
		byte blockIndex = block.getByte(startIndex + 6);
		// 文件占用的盘块数量(第7字节为占用的盘块数量)
		byte length = block.getByte(startIndex + 7);
		// 判断是文件还是目录
		if (FileAttribute.isCommonFile(attribute)) {
			directoryEntry = new File(name, typeName, attribute, blockIndex, length);
		} else if (FileAttribute.isFolder(attribute)) {
			directoryEntry = new Folder(name, typeName, attribute, blockIndex, length);
		}
		return directoryEntry;
	}

	/**
	 * 根据名字获取目录下目录项
	 * 
	 * @param index
	 * @return
	 */
	public DirectoryEntry getDirectoryEntry(String dirEntryName) {
		for (int i = 0; i < 8; i++) {
			DirectoryEntry entry = getDirectoryEntry(i);
			if (entry != null && entry.getCompleteName().equals(dirEntryName)) {
				if (entry.isCommonFile()) {
					return (File) entry;
				} else if (entry.isFolder()) {
					return (Folder) entry;
				}
			}
		}
		return null;
	}

	/**
	 * 获取子目录对应的目录项
	 * 
	 * @param name
	 * @return
	 */
	private Folder getDirectoryEntryOfFloder(String name) {
		for (int i = 0; i < 8; i++) {
			DirectoryEntry entry = getDirectoryEntry(i);
			// 判断是否存在文件且该文件为目录
			if (entry == null || !entry.isFolder()) {
				continue;
			}
			String completeName = entry.getCompleteName();
			// 判断目录名是否相同
			if (completeName.equals(name)) {
				return (Folder) entry;
			}
		}
		return null;
	}

	/**
	 * 获取文件对应的目录项
	 * 
	 * @param name
	 * @return
	 */
	private File getDirectoryEntryOfFile(String name) {
		for (int i = 0; i < 8; i++) {
			DirectoryEntry entry = getDirectoryEntry(i);
			// 判断是否存在文件且该文件为目录
			if (entry == null || !entry.isCommonFile()) {
				continue;
			}
			String completeName = entry.getCompleteName();
			// 判断文件名和类型名是否相同
			if (completeName.equals(name)) {
				return (File) entry;
			}
		}
		return null;
	}

	/**
	 * 获取当前目录下文件的绝对路径
	 * 
	 * @param file
	 * @return
	 */
	public String getAbsolutePath(String file) {
		// 根目录路径为"/"
		if (dirName.equals("/")) {
			return dirName + file;
		}
		return dirName + "/" + file;
	}

	/**
	 * 获取当前目录下的子目录
	 * 
	 * @param path
	 * @return
	 */
	public Directory getSubDir(String folderName) {
		// 获取子目录对应的目录项
		DirectoryEntry entry = getDirectoryEntryOfFloder(folderName);
		// 判断子目录是否存在
		if (entry != null) {
			int index = entry.blockIndex; // 获取子目录的起始盘块号
			System.out.println("目录:" + getAbsolutePath(folderName) + "所占用的盘块号为"
					+ index);
			return new Directory(Disk.getInstance().getBlock(index), getAbsolutePath(folderName));
		}
		System.out.println("目录:" + getAbsolutePath(folderName) + "不存在");
		return null;
	}

	/**
	 * 获取当前目录下的文件(包括内容)
	 * 
	 * @param name
	 * @param typeName
	 * @return
	 */
	public File getFileInfo(String fileName) {
		// 获取文件所在的盘块号
		File entry = getDirectoryEntryOfFile(fileName);
		if (entry == null) {
			System.out.println("文件:" + getAbsolutePath(fileName) + "不存在");
			return null;
		}
		int index = entry.blockIndex;// 获取文件的起始盘块号
		System.out.println("文件:" + getAbsolutePath(fileName) + "所占用的起始盘块号为"
				+ index);
		// 获取文件的实际内容
		byte[] content = getFileContent(index);
		entry.setContent(content);
		return entry;
	}

	/**
	 * 列出当前目录下的所有文件
	 */
	public ArrayList<DirectoryEntry> listFile() {
		ArrayList<DirectoryEntry> entries = new ArrayList<DirectoryEntry>();
		for (int i = 0; i < 8; i++) { // 每个目录最多8个文件(可能存放顺序不连续 所以要遍历一次)
			DirectoryEntry entry = getDirectoryEntry(i);
			if (entry != null) {
				entries.add(entry);
			}
		}
		return entries;
	}

	/**
	 * 删除文件
	 * 
	 * @return
	 */
	public boolean deleteFile(String fileName) {
		// 搜索该文件目录项
		File entry = getDirectoryEntryOfFile(fileName);
		// 判断该文件是否存在
		if (entry == null) {
			System.out.println("文件:" + getAbsolutePath(fileName) + "不存在");
			System.out.println("----------------");
			return false;
		}
		Disk disk = Disk.getInstance();
		FAT fat = disk.getFat();
		// 获取该文件占用的起始盘块号
		int index = entry.getBlockIndex();
		// 获取该盘块占用的全部盘块索引号
		ArrayList<Byte> blockIndexes = fat.getFileAllocateList(index);
		// 清空盘块内容
		disk.clearBlocks(blockIndexes);
		// 将fat上已占用的位置标记为空闲
		fat.clearFileAllocateList(index);
		// 清除目录项
		removeDirectoryEntry(fileName);

		// -------------------------------------
		System.out.println("删除文件:" + getAbsolutePath(fileName));
		System.out.print("该文件之前占用的盘块:[ ");
		for (int i = 0; i < blockIndexes.size(); i++) {
			System.out.print(blockIndexes.get(i) + " ");
		}
		System.out.println("]");
		System.out.println("----------------");
		// -------------------------------------

		return true;
	}

	/**
	 * 删除文件夹内所有内容(删除目录及目录下的所有文件)
	 * 
	 * @param folderName
	 * @return
	 */
	public boolean deleteFolder(String folderName) {
		Directory directory = getSubDir(folderName);
		// 判断文件夹是否存在
		if (directory == null) {
			System.out.println("文件夹:" + getAbsolutePath(folderName) + "不存在");
			System.out.println("----------------");
			return false;
		}

		// 遍历文件夹内的文件
		ArrayList<DirectoryEntry> entries = directory.listFile();
		for (int i = 0; i < entries.size(); i++) {
			DirectoryEntry entry = entries.get(i);
			// 判断是文件还是文件夹
			if (entry.isCommonFile()) {
				directory.deleteFile(entry.getCompleteName());
			} else if (entry.isFolder()) {
				directory.deleteFolder(entry.getCompleteName());
			}
		}

		FAT fat = Disk.getInstance().getFat();
		DirectoryEntry entry = getDirectoryEntryOfFloder(folderName);
		// 将fat上已占用的位置标记为空闲
		fat.clearFileAllocateList(entry.getBlockIndex());
		// 清除目录项
		removeDirectoryEntry(folderName);
		// -------------------------------------
		System.out.println("删除目录:" + getAbsolutePath(folderName));
		System.out.println("该文件之前占用的盘块:[ " + entry.getBlockIndex() + " ]");
		System.out.println("----------------");
		// -------------------------------------
		return true;
	}

	/**
	 * 获取父目录
	 */
	public Directory getParentDir() {
		// 判断是否为根目录
		if (dirName.equals("/")) {
			return this;
		}
		String parentDirName = dirName.substring(0, dirName.lastIndexOf("/"));
		return Directory.getDirectory(parentDirName);
	}

	/**
	 * 更新文件内容
	 * 
	 * @param name
	 * @param typeName
	 * @param newContent
	 * @return
	 */
	public boolean updateFileContent(String fileName, String newContent) {
		Disk disk = Disk.getInstance();
		FAT fat = disk.getFat();
		DirectoryEntry dirEntry = getDirectoryEntry(fileName);
		if (dirEntry == null) {
			System.out.println(getAbsolutePath(fileName) + "不存在");
			return false;
		}
		int dirEntryIndex = getDirectoryEntryIndex(fileName);
		int blockIndex = dirEntry.getBlockIndex();// 文件占用的起始盘块号
		int oldLength = dirEntry.getLength(); // 之前文件占用的盘块数
		int newLength = Block.getBlockLength(newContent.length() + 4); // 之后需要占用的盘块数
		ArrayList<Byte> oldBlockIndexes = fat.getFileAllocateList(blockIndex);

		// 文件长度不变
		if (newLength == oldLength) {
			saveFileContent(newContent.getBytes(), ByteUtil.ArrayListToByteArray(oldBlockIndexes));
		}
		// 文件长度变短
		else if (newLength < oldLength) {
			ArrayList<Byte> newBlockIndexes = new ArrayList<Byte>(fat.getFileAllocateList(blockIndex).subList(0, newLength));
			fat.cutDownFileAllocateList(blockIndex, newLength);
			// 清空之前占用的盘块内容
			disk.clearBlocks(oldBlockIndexes);
			// 保存内容
			saveFileContent(newContent.getBytes(), ByteUtil.ArrayListToByteArray(newBlockIndexes));
		}
		// 文件长度变长
		else {
			byte[] newBlockIndexes = fat.allocateBlock(newLength - oldLength);// 分配更多的空间
			System.out.println("磁盘空间不足");
			if (newBlockIndexes == null) {
				return false;
			}
			// 将新分配的空间与之前的空间连接起来
			fat.appendFileAllocateList(blockIndex, newBlockIndexes[0]);
			saveFileContent(newContent.getBytes(), ByteUtil.ArrayListToByteArray(fat.getFileAllocateList(blockIndex)));
		}
		// 更新目录项的长度属性
		setDirectoryEntryValue(dirEntryIndex, dirEntry.getName(), dirEntry.getTypeName(), dirEntry.getAttribute(), dirEntry.getBlockIndex(), (byte) newLength);
		return true;
	}

	/**
	 * 更换名字
	 * 
	 * @param oldFileName
	 * @param fileName
	 * @return
	 */
	public boolean rename(String oldName, String newName) {
		// 判断新的名字是否存在
		if (getDirectoryEntryIndex(newName) != -1) {
			System.out.println(getAbsolutePath(newName) + "已存在");
			return false;
		}
		int dirEntryIndex = getDirectoryEntryIndex(oldName);
		if (dirEntryIndex != -1) {
			// 获取原来的属性
			DirectoryEntry entry = getDirectoryEntry(dirEntryIndex);
			// 判断该目录项是文件还是目录
			if (entry.isCommonFile()) {
				String[] tokens = newName.split("\\."); // 分割文件名
				String name = tokens[0];
				String typeName = tokens[1];
				// 文件需要记录类型名
				setDirectoryEntryValue(dirEntryIndex, name.getBytes(), typeName.getBytes(), entry.getAttribute(), entry.getBlockIndex(), entry.getLength());
			} else if (entry.isFolder()) {
				setDirectoryEntryValue(dirEntryIndex, newName.getBytes(), entry.getTypeName(), entry.getAttribute(), entry.getBlockIndex(), entry.getLength());
			}
			return true;
		}
		System.out.println(getAbsolutePath(oldName) + "不存在");
		return false;
	}

	/**
	 * 移动文件或目录(只需移动目录项到新的目录下)
	 * 
	 * @param fileName
	 * @param newPath
	 * @return
	 */
	public boolean move(String dirEntryName, String newPath) {
		Directory newDirectory = Directory.getDirectory(newPath);
		// 判断新的目录下是否能添加文件
		if (!newDirectory.canAddDirectoryEntry()) {
			System.out.println(newPath + "目录下的文件数量已达8个");
			return false;
		}
		int dirEntryIndex = getDirectoryEntryIndex(dirEntryName);
		// 判断该目录项是否存在
		if (dirEntryIndex == -1) {
			System.out.println(getAbsolutePath(dirEntryName) + "不存在");
			return false;
		}
		DirectoryEntry entry = getDirectoryEntry(dirEntryIndex);
		// 将原来的目录项清空
		setDirectoryEntryValue(dirEntryIndex, new byte[] { 0, 0, 0 }, new byte[] {
				0, 0 }, (byte) 0, (byte) 0, (byte) 0);
		// 往新的目录添加目录项
		newDirectory.addDirectoryEntry(entry);
		return true;
	}

	/**
	 * 复制文件
	 * 
	 * @param fileName
	 * @param newPath
	 * @return
	 */
	public boolean copyFile(String fileName, String newPath) {
		// 获取文件目录项及其内容
		File file = getDirectoryEntryOfFile(fileName);
		if (file == null) {
			System.out.println(getAbsolutePath(fileName) + "不存在");
			return false;
		}
		file.setContent(getFileContent(file.getBlockIndex()));
		// 获取新路径
		Directory newDirectory = Directory.getDirectory(newPath);
		if (newDirectory == null) {
			System.out.println(newPath + "不存在");
			return false;
		}
		return newDirectory.addFile(file);
	}

	/**
	 * 获取任意目录
	 * 
	 * @param dir
	 * @return
	 */
	public static Directory getDirectory(String dir) {
		// 先设置当前目录为根目录
		Directory currentDir = Disk.getInstance().getRootDir();
		String[] tokens = dir.split("/");
		for (int i = 1; i < tokens.length; i++) {
			currentDir = currentDir.getSubDir(tokens[i]);
		}
		return currentDir;
	}

	/**
	 * 设置文件目录项的属性
	 * 
	 * @param dirEntryName
	 * @return
	 */
	public boolean setAttribute(String dirEntryName, byte attribute) {
		DirectoryEntry entry = getDirectoryEntry(dirEntryName);
		if (entry == null) {
			System.out.println(getAbsolutePath(dirEntryName) + "不存在");
			return false;
		}
		// 判断属性值是否合理
		if (attribute < 0 || attribute > 16) {
			System.out.println("文件属性错误");
			return false;
		}
		int dirEntryIndex = getDirectoryEntryIndex(dirEntryName);
		setDirectoryEntryValue(dirEntryIndex, entry.getName(), entry.getTypeName(), attribute, entry.getBlockIndex(), entry.getLength());
		return true;
	}

	/**
	 * 添加文件
	 * 
	 * @param fileName
	 * @return
	 */
	public boolean addFile(String fileName, String content) {
		String[] tokens = fileName.split("\\.");
		return addFile(new File(tokens[0].getBytes(), tokens[1].getBytes(), content.getBytes()));
	}

	/**
	 * 添加文件
	 * 
	 * @param fileName
	 * @return
	 */
	public boolean addFile(String fileName) {
		return addFile(fileName, "");
	}

	/**
	 * 添加文件夹
	 * 
	 * @param fileName
	 * @return
	 */
	public boolean addFolder(String folderName) {
		return addFolder(new Folder(folderName.getBytes()));
	}

	/**
	 * 打开文件
	 * 
	 * @param fileName
	 * @return
	 */
	public boolean openFile(String fileName, int operationType) {
		return OpenFileTable.getInstance().addItem(this, getDirectoryEntry(fileName), operationType);
	}

	/**
	 * 关闭文件
	 * 
	 * @param fileName
	 * @return
	 */
	public boolean closeFile(String fileName) {
		OpenFileTable.getInstance().removeItem(getAbsolutePath(fileName));
		return true;
	}

}
